home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
news
/
readers
/
skim-0.8
/
skim-0
/
skim-0.8.4
/
PostArticle.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-18
|
7KB
|
255 lines
/*
* NAME
* PostArticle.c
* USAGE
* Usage: PostArticle ArticleFile ...
* DESCRIPTION
* Post one or more articles to USENET.
* COPYRIGHT
* Skim - Off-line news reading package optimized for slow lines.
* Copyright (C) 1996 Rene W.J. Pijlman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* VERSION
* Skim version 0.8.4.
*/
#include <assert.h>
#include "Skim.h"
#include "SkimUtils.h"
#include "StandardIO.h"
#include "NNTPStream.h"
#include "Article.h"
#include "VarBuf.h"
FILE_ID("$Header: /home/rene/sys/CVS_MasterSourceRepository/skim/PostArticle.c,v 1.6 1996/02/18 11:40:20 rene Exp $");
/* Return a copy of an article in the format required by RFC 977. */
static VarBuf FormatAsRequiredByRFC977( VarBuf ArticleVB )
{
VarBuf New = VBCreate();
Boolean OnFirstPositionOfLine = True;
char * p;
for ( p = VBAsString(ArticleVB); *p; p++ )
{
if ( OnFirstPositionOfLine && *p == '.' )
{
VBAppendString( New, ".." );
}
else if ( *p == '\n' )
{
VBAppendString( New, "\r\n" );
}
else
{
VBAppendCharacter( New, *p );
}
OnFirstPositionOfLine = ( *p == '\n' );
}
return New;
}
/* ArticleToPost is in UNIX text file representation. */
static Boolean PostArticleToNewsServer(
StandardIO NewsServer, VarBuf ArticleToPost )
{
Boolean Success = True;
assert( NewsServer != NULL );
assert( SIOIsOpenForWrite(NewsServer) && SIOIsOpenForRead(NewsServer) );
SIOInternetCommand( NewsServer, "post" );
Success = CheckStatusResponse( NewsServer, NULL, "340", NULL,
DONT_TERMINATE_ON_ERROR );
if ( Success )
{
VarBuf FormattedAsRequiredByRFC977 =
FormatAsRequiredByRFC977( ArticleToPost );
SIOPrintf( NewsServer, "%V.\r\n", FormattedAsRequiredByRFC977 );
Success = CheckStatusResponse( NewsServer, NULL, "240",
NULL, DONT_TERMINATE_ON_ERROR );
VBDestroy( FormattedAsRequiredByRFC977 );
}
return Success;
}
static void PrepareForPost( Article ArticleUnderConstruction )
{
VarBuf Signature = NULL;
VarBuf X_NewsReader = NULL;
VarBuf From = NULL;
VarBuf Path = NULL;
VarBuf ReplyTo = NULL;
VarBuf Organization = NULL;
ItemsFromEnvironment( &Signature, &X_NewsReader, &From, &ReplyTo,
&Path, &Organization );
ArticlePrepareForPost( ArticleUnderConstruction, From, Path, ReplyTo,
Organization, X_NewsReader );
VBDestroy( Signature );
VBDestroy( X_NewsReader );
VBDestroy( From );
VBDestroy( Path );
VBDestroy( ReplyTo );
VBDestroy( Organization );
}
/* VB to Article, prepare for post, Article to VB. */
static Boolean PostArticleVB(
VarBuf ArticleVB, StandardIO * NewsServer, VarBuf * ArticleAsPosted )
{
Boolean Success = True;
Article ArticleUnderConstruction = ArticleCreate();
assert( ArticleAsPosted != NULL && *ArticleAsPosted == NULL );
ArticleSetVB( ArticleUnderConstruction, ArticleVB );
PrepareForPost( ArticleUnderConstruction );
if ( ArticleIsOKAndComplete( ArticleUnderConstruction ) )
{
*ArticleAsPosted = ArticleGetVB( ArticleUnderConstruction );
if ( *NewsServer == NULL )
{
*NewsServer = NNTPStreamOpen();
}
assert( *NewsServer != NULL );
if ( !PostArticleToNewsServer( *NewsServer, *ArticleAsPosted ) )
{
Success = False;
}
}
else
{
Success = False;
SIOPrintf( StandardError, "%V",
ArticleGetErrorMessages(ArticleUnderConstruction) );
}
ArticleDestroy( ArticleUnderConstruction );
assert ( !Success || *ArticleAsPosted != NULL );
return Success;
}
/* File management. */
static Boolean PostArticleFile(
const char * FileName, StandardIO * NewsServer )
{
Boolean Success = True;
VarBuf FullPath = VBCreate();
StandardIO ArticleFile = SIOCreate();
VarBuf ArticleVB = VBCreate();
VarBuf FullPathPosted = VBCreate();
StandardIO CopyInPosted = SIOCreate();
VarBuf ArticleAsPosted = NULL;
assert( FileName != NULL && strlen(FileName) > 0 );
VBPrintf( FullPath, "%s/Post/%s", SkimDirectory(), FileName );
SIOFileOpen( ArticleFile, VBAsString(FullPath), OpenModeRead );
VBReadFile( ArticleVB, ArticleFile );
SIOFileClose( ArticleFile );
Success = PostArticleVB( ArticleVB, NewsServer, &ArticleAsPosted );
if ( Success )
{
assert( VBSize(ArticleAsPosted) > 0 );
VBPrintf( FullPathPosted, "%s/Posted/%s", SkimDirectory(), FileName );
SIOFileOpen( CopyInPosted, VBAsString(FullPathPosted),
OpenModeWriteDiscardOld );
VBWriteFile( ArticleAsPosted, CopyInPosted );
SIOFileClose( CopyInPosted );
/* Posted OK, kept copy, so remove the article file now. */
SIORemove( VBAsString(FullPath) );
}
VBDestroy( FullPath );
SIODestroy( ArticleFile );
VBDestroy( ArticleVB );
VBDestroy( FullPathPosted );
SIODestroy( CopyInPosted );
VBDestroy( ArticleAsPosted );
return Success;
}
/* Loop over all filename arguments. */
int main( int argc, char **argv )
{
Boolean AllArticlesPosted = True;
StandardIO NewsServer = NULL;
int i;
if ( argc < 1 )
{
SIOPrintf( StandardError, "%s\n",
"Usage: PostArticle ArticleFile ..." );
exit( EXIT_FAILURE );
}
for ( i = 1; i < argc; i++ )
{
if ( strlen(argv[i]) > 0 )
{
SIOPrintf( StandardOutput, "Posting article %s.\n", argv[i] );
SIOFlushBuffers( StandardOutput );
if ( PostArticleFile( argv[i], &NewsServer ) )
{
SIOPrintf( StandardOutput,
"Article %s posted successfully.\n", argv[i] );
}
else
{
AllArticlesPosted = False;
SIOPrintf( StandardError, "Error: Article %s not posted.\n",
argv[i] );
}
}
}
if ( !AllArticlesPosted && argc > 2 )
{
SIOPrintf( StandardError,
"One or more articles were not posted successfully.\n" );
}
NNTPStreamClose( NewsServer );
return AllArticlesPosted ? EXIT_SUCCESS : EXIT_FAILURE;
}